package com.wondersgroup.core.frame;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.wondersgroup.core.util.TimeOrDateUtils;

/**
 * Controller的父类，提供一些公用的方法
 * 
 * @author duanjianguo
 * 
 */
public class BaseController {
    protected int companyId;
	
    public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
    public static final MediaType APPLICATION_TEXT_UTF8 = new MediaType(MediaType.TEXT_HTML.getType(), MediaType.TEXT_HTML.getSubtype(), Charset.forName("utf8"));

	
	
        
        
        /**
         * 获取当前登录设备使用的应用版本号
         * @return 
         */
        protected Integer getLoginAppVersion(){
            ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
            HttpSession session = attr.getRequest().getSession(true);
            Object v = session.getAttribute("appVersion");
            Integer version = null;
            if(v!=null){
                if(v instanceof Integer){
                    version = (Integer) v;
                }else{
                    version = Integer.valueOf(v.toString());
                }
            }
            return version;
        }
        
	/**
	 * 将返回值对象包装为使用JSON格式的ResponseEntity并返回
	 * 
	 * @param body
	 * @param status
	 * @return
	 */
	protected <T> ResponseEntity<T> returnJSONWithStatus(T body, HttpStatus status) {
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(APPLICATION_JSON_UTF8);
		return new ResponseEntity<T>(body, headers, status);
	}
	
	/**
	 * 将返回值对象包装为使用JSON格式的ResponseEntity并返回
	 * 
	 * @param body
	 * @param status
	 * @return
	 */
	protected <T> ResponseEntity<T> returnJSONWithStatusForIE(T body, HttpStatus status) {
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(APPLICATION_TEXT_UTF8);
		return new ResponseEntity<T>(body, headers, status);
	}

	/**
	 * 返回MultipartFile文件Map使用文件名为key
	 * 
	 */
	protected Map<String, MultipartFile> getMultipartFileNameMap(MultipartFile[] qualiFiles) {
		// 提取上传文件
		Map<String, MultipartFile> fileMap = new HashMap<String, MultipartFile>();
		if (qualiFiles != null && qualiFiles.length > 0) {
			for (MultipartFile file : qualiFiles) {
				if (file != null && file.getSize() > 0) {
					String fileName = file.getOriginalFilename();
					fileMap.put(fileName, file);
				}
			}
		}
		return fileMap;
	}
	
	/**
	 * 返回MultipartFile文件Map使用文件名为key
	 * 
	 */
	protected Map<String, MultipartFile> getMultipartFileNameMap(List<MultipartFile> qualiFiles) {
		// 提取上传文件
		Map<String, MultipartFile> fileMap = new HashMap<String, MultipartFile>();
		if (qualiFiles != null && qualiFiles.size() > 0) {
			for (MultipartFile file : qualiFiles) {
				if (file != null && file.getSize() > 0) {
					String fileName = file.getOriginalFilename();
					fileMap.put(fileName, file);
				}
			}
		}
		return fileMap;
	}
	
	/**
	 * 从request中获取所有的上传文件
	 * @param request
	 * @return
	 */
	protected List<MultipartFile> getMultipartFilesFromRequest(HttpServletRequest request){
		List<MultipartFile> multipartFiles = new ArrayList<MultipartFile>();
		if(request!=null && request instanceof MultipartHttpServletRequest){
			MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
			MultiValueMap<String, MultipartFile> fMap = multipartHttpServletRequest.getMultiFileMap();
			if(fMap!=null && fMap.size()>0){
				for(Entry<String, List<MultipartFile>> entry : fMap.entrySet()){
					List<MultipartFile> files = entry.getValue();
					if(files!=null && files.size()>0){
						multipartFiles.addAll(files);
					}
				}
			}
		}
		return multipartFiles;
	}
	
	/**
	 * 从request中获取所有的上传文件并以Map形式返回
	 * @param request
	 * @return
	 */
	protected Map<String, List<MultipartFile>> getMultipartFileMapFromRequest(HttpServletRequest request){
		if(request!=null && request instanceof MultipartHttpServletRequest){
			MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
			MultiValueMap<String, MultipartFile> fMap = multipartHttpServletRequest.getMultiFileMap();
			if(fMap!=null){
				return fMap;
			}
		}
		return null;
	}
	
	/**
	 * 把对象转换成json，忽略 null的属性。
	 * @param obj
	 * @return Map
	 * @throws JsonProcessingException
	 */
	
	@SuppressWarnings("rawtypes")
	protected Map getCompactJSONMapFromObject(Object obj) throws Exception {
		ObjectMapper om = new ObjectMapper();
		om.setSerializationInclusion(Include.NON_NULL);
		om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
		om.configure(SerializationFeature.WRAP_ROOT_VALUE, false);
		om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		om.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, false);
		om.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
		String json  = om.writeValueAsString(obj);
		Map map = om.readValue(json, Map.class);
		return map;
	}
	
	/**
	 * 将一个list中的元素属性拷贝到另一个list的元素中去
	 * @param targetList 目标list, 可以为null
	 * @param targetClass 目标元素的类型
	 * @param sourceList 来源list
	 * @param whiteList 属性白名单
	 * @param blackList 属性黑名单
	 * @param ignoreNullValue
	 * @return
	 */
	protected <T> List<T> toEntityList(List<T> targetList, Class<T> targetClass, List<? extends Object> sourceList, 
			Set<String> whiteList, Set<String> blackList, boolean ignoreNullValue){
		if (sourceList != null) {
			if(targetList==null){
				targetList = new ArrayList<T>();
			}
			for(Object sourceInstance : sourceList){
				try {
					T targetInstance = CommonDomainDTO.toEntity(null, targetClass, sourceInstance, whiteList, blackList, ignoreNullValue);
					if(targetInstance!=null){
						targetList.add(targetInstance);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			return targetList;
		}
		return null;
	}
	
	/**
	 * 将一个QueryResult中的元素属性拷贝到另一个QueryResult的元素中去
	 * @param targetResult 目标QueryResult, 可以为null
	 * @param targetClass 目标元素的类型
	 * @param sourceResult 来源QueryResult
	 * @param whiteList 属性白名单
	 * @param blackList 属性黑名单
	 * @param ignoreNullValue
	 * @return
	 */
	protected <T> QueryResult<T> toEntityList(QueryResult<T> targetResult, Class<T> targetClass, QueryResult<? extends Object> sourceResult, 
			Set<String> whiteList, Set<String> blackList, boolean ignoreNullValue){
		if(sourceResult !=null){
			List<T> targetList = null;
			if(targetResult == null){
				targetResult = new QueryResult<T>(targetList, sourceResult.getTotalRecord(), sourceResult.getCurrPageNo(), sourceResult.getPageSize());
			}
			
			if(sourceResult.getResultList()!=null){
				List<? extends Object> sourceList = sourceResult.getResultList();
				targetList = toEntityList(targetList, targetClass, sourceList, whiteList, blackList, ignoreNullValue);
				targetResult.setResultList(targetList);
			}
			return targetResult;
		}
		return null;
	}
	
	
	protected int getIntParam(Map paramMap,String key) {
		int paramValue;
		String value = (String)paramMap.get(key);
		try {
			paramValue = Integer.parseInt(value);
		} catch (NumberFormatException e) {
			paramValue = Integer.MIN_VALUE;
		}
		return paramValue;
	}
	
	protected int getIntParam(HttpServletRequest request,String key) {
		int paramValue;
		String value = (String)request.getParameter(key);
		try {
			paramValue = Integer.parseInt(value);
		} catch (Exception e) {
			paramValue = Integer.MIN_VALUE;
		}
		return paramValue;
	}
	
	protected String getStringParam(Map paramMap,String key) {
		String value;
		try {
			value = (String)paramMap.get(key);
		} catch (Exception e) {
			value = "";
		}
		return value;
	}
	
	protected String getStringParam(HttpServletRequest request,String key) {
		String value;
		try {
			value = (String)request.getParameter(key);
		} catch (Exception e) {
			value = "";
		}
		return value;
	}
	
	protected Date getDateParam(HttpServletRequest request,String key) {
		Date paramValue=null;
		String value = (String)request.getParameter(key);
		try {
			paramValue = TimeOrDateUtils.parseDate(value, TimeOrDateUtils.FULL_YMD);
		} catch (Exception e) {
			paramValue = null;
		}
		return paramValue;
	}
	protected Date getDateParam(Map paramMap,String key) {
		Date paramValue=null;
		String value = (String)paramMap.get(key);
		try {
			paramValue = TimeOrDateUtils.parseDate(value, TimeOrDateUtils.FULL_YMD);
		} catch (Exception e) {
			paramValue = null;
		}
		return paramValue;
	}
	protected <T> T getDTOFromString(String dtoString,Class<T> clazz) {
		T dto=null;
		try {
    		ObjectMapper mapper = new ObjectMapper();
    		mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    		dto = mapper.readValue(dtoString, clazz);
		} catch (Exception e) {
			throw new TraceException(e);
		}
		
		return dto;
	}
	
	protected HttpServletRequest getRequest(){
		ServletRequestAttributes sra =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    	HttpServletRequest request = sra.getRequest();
		return request;
	}
	
	protected void addSysOperationHistory(String actionType, String actionDetail){
		HttpServletRequest request = getRequest();
		request.setAttribute("AddhistoryFlag", true);
		request.setAttribute("actionType", actionType);
		request.setAttribute("actionDetail", actionDetail);
	}
	
	protected void addSysOperationHistory(String actionDetail){
		addSysOperationHistory(null, actionDetail);
	}
	
	protected List<Integer> convertStringToIntegerList(String attIds) {
		List<Integer> idList = new ArrayList<Integer>();
		if(StringUtils.isNotEmpty(attIds)) {
			String[] idArray = attIds.split(",");
			for (int i = 0; i < idArray.length; i++) {
				String idString = idArray[i];
				Integer id = Integer.parseInt(idString);
				if(id!=null) {
					idList.add(id);
				}
			}
		}
		return idList;
	}
}
